package hk.com.fgoproduction.getdroplets.Activity

import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.webkit.WebView
import android.webkit.WebViewClient
import hk.com.fgoproduction.getdroplets.Activity.MainActivity
import hk.com.fgoproduction.getdroplets.Lib.Common.ToolInstance.LogInstance
import hk.com.fgoproduction.getdroplets.Lib.Common.ThisApplication
import hk.com.fgoproduction.getdroplets.R
import kotlinx.android.synthetic.main.auth.*
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.net.URL
import java.util.*
import javax.net.ssl.HttpsURLConnection

class OAuthActivity : Activity(), ThisApplication.BgThreadCallback {

    private val showLog = false

    private var code = ""
    private var result = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.auth)

        getCode()
    }

    private fun getCode() {

        val callback = resources.getString(R.string.callback)
        //val url = authUrl()
        val pathUrl = StringBuilder()
                .append("https://www.dropbox.com/1/oauth2/authorize")
                .append("?locale=").append(Locale.getDefault().toString())
                .append("&client_id=").append(resources.getString(R.string.app_key))
                .append("&response_type=code")
                .append("&redirect_uri=").append(resources.getString(R.string.callback))
                .toString()

        authView.settings.javaScriptEnabled = true
        authView.settings.builtInZoomControls = true

        authView.setWebViewClient(object : WebViewClient() {
            override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                LogInstance.log("Auth Url", url as String, LogInstance.LogType.DEBUG, showLog)
                (application as ThisApplication).runOnBgWithCb(Runnable { checkUrl(view, url, favicon) }, this@OAuthActivity)
            }

            private fun checkUrl(view: WebView?, url: String, favicon: Bitmap?) {
                if (url.startsWith(callback)) {
                    code = Uri.parse(url).getQueryParameter("code")

                    if (code.isEmpty()) {
                        super.onPageStarted(view, url, favicon)
                    } else {
                        LogInstance.log("$this", "code=" + code, LogInstance.LogType.DEBUG, showLog)
                        getAccessToken()
                    }
                } else {
                    LogInstance.log("Auth failure", "URL = $url", LogInstance.LogType.ERROR, showLog)
                }
            }

        })

        authView.loadUrl(pathUrl)
    }

    private fun getAccessToken() {
        val tokenUrl = URL("https://api.dropboxapi.com/1/oauth2/token")
        val con: HttpsURLConnection = tokenUrl.openConnection() as HttpsURLConnection

        postTokenRequest(con)
        getToken(con)
        backToMain()
    }

    @Throws(IOException::class)
    private fun getToken(con: HttpsURLConnection) {
        val `in` = BufferedReader(InputStreamReader(con.inputStream))
        var buffer: String
        val response = StringBuffer()

        while (true) {
            buffer = `in`.readLine() ?: break
            response.append(buffer)
        }
        `in`.close()
        LogInstance.log("$this", response.toString(), LogInstance.LogType.DEBUG, showLog)
        result = response.toString()
    }

    @Throws(IOException::class)
    private fun postTokenRequest(con: HttpsURLConnection) {
        val param = StringBuilder()
                .append("code=").append(code)
                .append("&grant_type=").append("authorization_code")
                .append("&client_id=").append(resources.getString(R.string.app_key))
                .append("&client_secret=").append(resources.getString(R.string.app_secret))
                .append("&redirect_uri=").append(resources.getString(R.string.callback))
                .toString()

        con.requestMethod = "POST"
        con.doOutput = true
        val out = OutputStreamWriter(con.outputStream)
        out.write(param)
        out.flush()
        out.close()

        if (con.responseCode != 200)
            throw IOException("\nCODE: ${con.responseCode}\tHTTP ERROR!\tCheck $this")
    }

    private fun backToMain() {
        val intent = Intent(this@OAuthActivity, MainActivity::class.java)
        intent.putExtra("result", result)
        setResult(RESULT_OK, intent)
        finish()
    }

    override fun threadFinish() {
        LogInstance.log("OAuth", "Page handling finished", LogInstance.LogType.VERBOSE, showLog)
    }
}